home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i060: Jove, an emacs variant, version 4.9, Part04/21
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
- Posting-number: Volume 14, Issue 60
- Archive-name: jove4.9/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 21)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./Makefile'\"
- else
- echo shar: Extracting \"'./Makefile'\" \(8207 characters\)
- sed "s/^X//" >'./Makefile' <<'END_OF_FILE'
- X###########################################################################
- X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE #
- X# is provided to you without charge, and with no warranty. You may give #
- X# away copies of JOVE, including sources, provided that this notice is #
- X# included in all the files. #
- X###########################################################################
- X
- X# TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If
- X# your system does not remove subdirectories of /tmp on reboot (lots do
- X# remove them these days) then it makes sense to make TMPDIR be /tmp/jove.
- X# But if you want to recover buffers on system crashes, you should create a
- X# directory that doesn't get clearned upon reboot, and use that instead.
- X# You would probably want to clean out that directory periodically with
- X# /etc/cron. LIBDIR is for online documentation, the PORTSRV process,
- X# RECOVER, and the system-wide .joverc file. BINDIR is where to put the
- X# executables JOVE and TEACHJOVE. MANDIR is where the manual pages go for
- X# JOVE, RECOVER and TEACHJOVE. MANEXT is the extension for the man pages,
- X# e.g., jove.1 or jove.l or jove.m.
- X
- DESTDIR =
- TMPDIR = /tmp
- LIBDIR = /usr/local/lib/jove
- BINDIR = /usr/local
- MANDIR = /usr/man/manl
- MANEXT = l
- SHELL = /bin/csh
- X
- X# These should all just be right if the above ones are.
- JOVE = $(DESTDIR)$(BINDIR)/jove
- TEACHJOVE = $(DESTDIR)$(BINDIR)/teachjove
- RECOVER = $(DESTDIR)$(LIBDIR)/recover
- PORTSRV = $(DESTDIR)$(LIBDIR)/portsrv
- JOVERC = $(DESTDIR)$(LIBDIR)/.joverc
- CMDS.DOC = $(DESTDIR)$(LIBDIR)/cmds.doc
- TEACH-JOVE = $(DESTDIR)$(LIBDIR)/teach-jove
- JOVEM = $(DESTDIR)$(MANDIR)/jove.$(MANEXT)
- TEACHJOVEM = $(DESTDIR)$(MANDIR)/teachjove.$(MANEXT)
- X
- X# Select the right libraries for your system.
- X# 2.10BSD:LIBS = -ltermcap
- X# v7: LIBS = -ltermcap
- X# 4.1BSD: LIBS = -ltermcap -ljobs
- X# 4.2BSD: LIBS = -ltermcap
- X# 4.3BSD: LIBS = -ltermcap
- X# SysV Rel. 2: LIBS = -lcurses
- X# SCO Xenix: LIBS = -ltermcap -lx
- X
- LIBS = -ltermcap
- X
- X# If you are not VMUNIX (vax running Berkeley Version 4), you must specify
- X# the -i flags (split I/D space) and maybe the -x option (for adb to work).
- X# 2.10BSD:LDFLAGS =
- X# v7: LDFLAGS =
- X# 4.1BSD: LDFLAGS =
- X# 4.2BSD: LDFLAGS =
- X# 4.3BSD: LDFLAGS =
- X# SysV Rel. 2: LDFLAGS = -Ml
- X# SCO Xenix: LDFLAGS = -Ml -F 3000
- X#
- X# SEPFLAG should be:
- X# not on a PDP-11: SEPFLAG =
- X# PDP-11 with separate I&D: SEPFLAG = -i
- X# PDP-11 without separate I&D: SEPFLAG = -n
- X#
- X
- LDFLAGS =
- X
- SEPFLAG =
- X
- X# for SCO Xenix, set
- X# MEMFLAGS = -Mle
- X# CFLAGS = -LARGE -O -F 3000 -K -Mle (say -Mle2 for an 80286)
- X
- CFLAGS = -O
- X
- BASESEG = funcdefs.o keymaps.o argcount.o ask.o buf.o ctype.o delete.o \
- X disp.o insert.o io.o jove.o malloc.o marks.o misc.o re.o \
- X screen.o table.o tune.o util.o vars.o version.o
- OVLAY1 = abbrev.o rec.o paragraph.o fmt.o
- OVLAY2 = c.o wind.o fp.o move.o
- OVLAY3 = extend.o macros.o
- OVLAY4 = iproc.o re1.o
- OVLAY5 = proc.o scandir.o term.o case.o
- X
- OBJECTS = $(BASESEG) $(OVLAY1) $(OVLAY2) $(OVLAY3) $(OVLAY4) $(OVLAY5)
- X
- C_SRC = funcdefs.c abbrev.c argcount.c ask.c buf.c c.c case.c ctype.c \
- X delete.c disp.c extend.c fp.c fmt.c insert.c io.c iproc.c \
- X jove.c macros.c malloc.c marks.c misc.c move.c paragraph.c \
- X proc.c re.c re1.c rec.c scandir.c screen.c table.c term.c util.c \
- X vars.c version.c wind.c getch.c mac.c
- X
- SOURCES = $(C_SRC) portsrv.c recover.c setmaps.c teachjove.c
- X
- HEADERS = ctype.h io.h jove.h re.h rec.h table.h temp.h termcap.h \
- X tune.h externs.h mac.h
- X
- DOCS = doc/cmds.doc.nr doc/example.rc doc/jove.1 doc/jove.2 doc/jove.3 \
- X doc/jove.4 doc/jove.5 doc/jove.nr doc/system.rc \
- X doc/teach-jove doc/teachjove.nr doc/README doc/jove.qref
- X
- MISC = Makefile Ovmakefile Makefile.dos tune.dos tune.template \
- X README Readme.dos Readme.mac iproc-pipes.c iproc-ptys.c
- X
- SUPPORT = teachjove.c recover.c setmaps.c portsrv.c keymaps.txt \
- X macvert.c menumaps.txt mjovers.Hqx
- X
- BACKUPS = $(HEADERS) $(C_SRC) $(DOCS) $(SUPPORT) $(MISC)
- X
- all: sdate xjove recover teachjove portsrv macvert edate
- X
- sdate:
- X @echo "**** make started at `date` ****"
- X
- edate:
- X @echo "**** make completed at `date` ****"
- X
- xjove: $(OBJECTS)
- X $(CC) $(LDFLAGS) -o xjove $(OBJECTS) $(LIBS)
- X @-size xjove
- X
- gjove: $(OBJECTS)
- X ld -X /lib/gcrt0.o -o gjove $(OBJECTS) -lc $(LIBS)
- X @-size gjove
- X
- ovjove: $(OBJECTS)
- X ld $(SEPFLAG) $(LDFLAGS) -X /lib/crt0.o \
- X -Z $(OVLAY1) \
- X -Z $(OVLAY2) \
- X -Z $(OVLAY3) \
- X -Z $(OVLAY4) \
- X -Z $(OVLAY5) \
- X -Y $(BASESEG) \
- X -o xjove $(LIBS) -lc; \
- X @-size xjove
- X
- portsrv: portsrv.o
- X $(CC) $(LDFLAGS) -o portsrv $(SEPFLAG) portsrv.o $(LIBS)
- X
- recover: recover.o tune.o rec.h temp.h
- X $(CC) $(LDFLAGS) -o recover $(SEPFLAG) recover.o tune.o $(LIBS)
- X
- teachjove: teachjove.o
- X $(CC) $(LDFLAGS) -o teachjove $(SEPFLAG) teachjove.o $(LIBS)
- X
- setmaps: setmaps.o funcdefs.c
- X $(CC) $(LDFLAGS) -o setmaps setmaps.o
- X
- teachjove.o: teachjove.c /usr/include/sys/types.h /usr/include/sys/file.h
- X cc -c $(CFLAGS) -DTEACHJOVE=\"$(TEACH-JOVE)\" teachjove.c
- X
- X# don't optimize setmaps.c because it produces bad code in some places
- X# for some reason
- setmaps.o: funcdefs.c keymaps.txt
- X $(CC) $(MEMFLAGS) -c setmaps.c
- X
- X# ignore error messages from setmaps
- X# it doesn't understand ifdefs
- X
- keymaps.c: setmaps keymaps.txt
- X -setmaps < keymaps.txt > keymaps.c
- X
- keymaps.o: keymaps.c jove.h
- X
- tune.c: Makefile tune.template
- X @echo "/* Changes should be made in Makefile, not to this file! */" > tune.c
- X @echo "" >> tune.c
- X @sed -e 's;TMPDIR;$(TMPDIR);' \
- X -e 's;LIBDIR;$(LIBDIR);' \
- X -e 's;BINDIR;$(BINDIR);' \
- X -e 's;SHELL;$(SHELL);' tune.template >> tune.c
- X
- iproc.o: iproc-ptys.c iproc-pipes.c iproc.c
- X $(CC) -c $(CFLAGS) iproc.c
- X
- macvert: macvert.c
- X $(CC) $(CFLAGS) -o macvert macvert.c
- X
- X# install doesn't work for Xenix (no install program)
- X
- install: $(DESTDIR)$(LIBDIR) $(TEACH-JOVE) $(CMDS.DOC) $(JOVERC) \
- X $(PORTSRV) $(RECOVER) $(JOVE) $(TEACHJOVE) $(JOVEM) \
- X $(RECOVERM) $(TEACHJOVEM)
- X
- X$(DESTDIR)$(LIBDIR):
- X -mkdir $(DESTDIR)$(LIBDIR)
- X
- X$(TEACH-JOVE): doc/teach-jove
- X install -c -m 644 doc/teach-jove $(TEACH-JOVE)
- X
- doc/cmds.doc: doc/cmds.doc.nr doc/jove.4 doc/jove.5
- X nroff doc/cmds.doc.nr doc/jove.4 doc/jove.5 > doc/cmds.doc
- X
- X$(CMDS.DOC): doc/cmds.doc
- X install -c -m 644 doc/cmds.doc $(CMDS.DOC)
- X
- X$(JOVERC): doc/system.rc
- X install -c -m 644 doc/system.rc $(JOVERC)
- X
- X$(PORTSRV): portsrv
- X install -c -s -m 755 portsrv $(PORTSRV)
- X
- X$(RECOVER): recover
- X install -c -s -m 755 recover $(RECOVER)
- X
- X$(JOVE): xjove
- X install -c -m 755 xjove $(JOVE)
- X
- X$(TEACHJOVE): teachjove
- X install -c -s -m 755 teachjove $(TEACHJOVE)
- X
- X$(JOVEM): doc/jove.nr
- X @sed -e 's;TMPDIR;$(TMPDIR);' \
- X -e 's;LIBDIR;$(LIBDIR);' \
- X -e 's;SHELL;$(SHELL);' doc/jove.nr > /tmp/jove.nr
- X install -m 644 /tmp/jove.nr $(JOVEM)
- X
- X$(TEACHJOVEM): doc/teachjove.nr
- X @sed -e 's;TMPDIR;$(TMPDIR);' \
- X -e 's;LIBDIR;$(LIBDIR);' \
- X -e 's;SHELL;$(SHELL);' doc/teachjove.nr > /tmp/teachjove.nr
- X install -m 644 /tmp/teachjove.nr $(TEACHJOVEM)
- X
- echo:
- X @echo $(C-FILES) $(HEADERS)
- X
- lint:
- X lint -n $(C_SRC) tune.c keymaps.c
- X @echo Done
- X
- tags:
- X ctags -w $(C_SRC) $(HEADERS) iproc-ptys.c
- X
- ciall:
- X ci $(BACKUPS)
- X
- coall:
- X co $(BACKUPS)
- X
- jove.shar:
- X shar $(BACKUPS) > jove.shar
- X
- backup: $(BACKUPS)
- X tar chf backup $(BACKUPS)
- X
- tape-backup:
- X tar c $(BACKUPS)
- X
- srcdownload:
- X kermit -s $(SUPPORT) $(MISC) $(HEADERS) $(C_SRC)
- X
- docdownload:
- X kermit -s $(DOCS)
- X
- touch:
- X touch $(OBJECTS)
- X
- clean:
- X rm -f a.out core *.o keymaps.c tune.c xjove portsrv recover setmaps \
- X teachjove macvert
- X
- X# This version only works under 4.3BSD
- X#depend:
- X# for i in ${SOURCES} ; do \
- X# cc -M ${CFLAGS} $$i | awk ' { if ($$1 != prev) \
- X# { if (rec != "") print rec; rec = $$0; prev = $$1; } \
- X# else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
- X# else rec = rec " " $$2 } } \
- X# END { print rec } ' >> makedep; done
- X# echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
- X# echo '$$r makedep' >>eddep
- X# echo 'w' >>eddep
- X# cp Makefile Makefile.bak
- X# ed - Makefile < eddep
- X# rm eddep makedep
- X# echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
- X# echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
- X# echo '# see make depend above' >> Makefile
- X#
- X## DO NOT DELETE THIS LINE -- make depend uses it
- END_OF_FILE
- if test 8207 -ne `wc -c <'./Makefile'`; then
- echo shar: \"'./Makefile'\" unpacked with wrong size!
- fi
- # end of './Makefile'
- fi
- if test -f './README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./README'\"
- else
- echo shar: Extracting \"'./README'\" \(8923 characters\)
- sed "s/^X//" >'./README' <<'END_OF_FILE'
- X###########################################################################
- X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE #
- X# is provided to you without charge, and with no warranty. You may give #
- X# away copies of JOVE, including sources, provided that this notice is #
- X# included in all the files. #
- X###########################################################################
- X
- To make JOVE edit Makefile to set the right directories for the binaries,
- on line documentation, the man pages, and the TMP files and select the
- appropriate load command (see SEPFLAG in Makefile). (IMPORTANT! read the
- Makefile carefully.) "tune.c" will be created from "tune.template" by
- MAKE automatically, and it will use the directories you specified in the
- Makefile. (NOTE: You should never edit tune.c directly because your
- changes will be undone by the next make. If you want to make a change to
- a part of tune.c that isn't a directory name, you should edit
- tune.template.) Next you must edit "tune.h" selecting the compile time
- options you care about. See below for a description of all the compile
- time options. You can type "make" to compile XJOVE, PORTSRV (this is
- compiled but not used on 4.2+ systems), RECOVER TEACHJOVE, and
- MACVERT. NOTE: make won't work if it fires up /bin/csh for the shell
- commands. Test them out to see if they work. If they do, type "make
- install" to install everything where it belongs.
- X
- Here are some things to consider for deciding where to put the tmp files.
- TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If
- your system does not remove subdirectories of /tmp on reboot (lots do
- remove them these days) then it makes sense to make TMPDIR be /tmp/jove.
- But if you want to recover buffers on system crashes, you should create a
- directory that doesn't get cleared upon reboot, and use that instead.
- You would probably want to clean out that directory periodically with
- X/etc/cron.
- X
- For the pdp11 version there is the Ovmakefile. This has only been tested
- on 2.9bsd. It works pretty well, actually, and it is possible to turn on
- all the compile time options with this version.
- X
- Bug reports: If you find bugs in JOVE I would appreciate hearing about
- them. (My net address is at end of this message.) So, send me the bug
- reports. If the bug isn't already fixed, I will ask you to send me the
- fix. If you haven't found the bug, I may be able to, so don't wait until
- you have found it. If you make improvements to JOVE and want them
- incorporated into the official version, send me a message explaining what
- the change is, and I will decide whether I want to include it. If it is
- possible for your change to be #ifdef'd in, that would be best, since I
- want to avoid making JOVE huge. For instance, if it's a new package type
- thing (say, like word abbrev. mode, or something) then it would be best
- if that were a compile-time option. I will send out periodic updates to
- mod.sources. I will report all significant bug fixes there, and to
- net.emacs as well.
- X
- Here's a list of the compile time options and what they mean:
- X
- ABBREV - Enables word-abbrev-mode which again is nice for paper writers.
- X
- BACKUPFILES - This enables backing up files on write. I guess lots of
- X people like this feature. It enables the feature but you
- X can still control whether files are backed up with the
- X make-backup-files variable.
- X
- BIFF - This enables turning on and off BIFF so your screen doesn't
- X get messed up with messages from BIFF.
- X
- BSD4_2 - Obviously, if you're a Berkeley 4.2 system.
- X
- BSD4_3 - If you're running a Berkeley 4.3 or 2.10 system.
- X This will automatically define BSD4_2, also.
- X
- CHDIR - This enables the directory commands; PUSHD, POPD, DIRS and
- X CD. These simulate the csh commands exactly, I think. As
- X a side-effect, absolute path names are enabled, which means
- X JOVE parses file names for "." and ".." and all that to get
- X at what you REALLY mean. It's nicer when this is enabled,
- X but not essential.
- X
- CMT_FMT - This enables code to format and indent C comments.
- X
- ID_CHAR - Enables support for Insert/Delete character on terminals
- X that have those capabilities. Couple of problems with this code:
- X it's large, takes up lots of I space which is a problem for the
- X smaller computers (pdp11). Also, it isn't particularly smart
- X and sometimes does really stupid things. It sometimes uses
- X insert/delete character when simply redrawing would have been
- X faster. And if you look at code you'll understand why I don't
- X like it all that much.
- X
- IPROCS - Nice feature which lets you run interactive UNIX commands in
- X windows. In particular, there is a shell command built
- X in which starts up an interactive shell in a window. This works
- X only on systems with JOB_CONTROL since it relies on the fancy
- X signal mechanism.
- X
- JOB_CONTROL - Versions of UNIX that have the job control facility.
- X Berkeley 2.9-10 systems, and the 4.1-3 systems I know have
- X job stopping, so if you're one of those, define
- X this. The reason MENLO_JCL is defined when JOB_CONTROL
- X is that the 2.9 signal.h file only defines all of the job
- X stopping signals only when MENLO_JCL is defined.
- X
- LISP - Enables Lisp Mode. This includes code to indent "properly"
- X for Lisp code and new routines to move over s-expressions.
- X You probably won't want (or need) this on PDP-11's.
- X
- MY_MALLOC - Use the older version of malloc that is more memory efficient
- X than the newer 4BSD version. The 4BSD version places more
- X importance on the speed of the allocation than the amount of
- X memory it uses. Make your choice ... JOVE hardly ever calls
- X malloc, anyway, relatively speaking, since it allocates
- X lines in big chunks. NOTE: This doesn't seem to work on suns
- X and the iAPX286.
- X
- PIPEPROCS - If NOT defined, JOVE will use Berkeley pseudo-ttys when
- X doing interactive processes. This is infinitely better,
- X since you get job control and all that stuff on i-procs.
- X If defined, the portsrv program will have to be made, and
- X all communication between jove and i-procs will be done using
- X pipes.
- X
- RESHAPING - This is for BRL or Berkeley 4.3 and 2.10 systems. When the
- X window size of the terminal jove is running in is changed
- X a SIGWINCH is sent to all processes in the tty group. This
- X define enables code in jove to catch that signal and reshape
- X its windows.
- X
- SPELL - Enables the spell-buffer and parse-spelling-errors commands.
- X They are nice especially if you have lots of paper writers.
- X
- WIRED_TERMS - Include compiled-in hard-wired code for certain terminals,
- X like the Concept 100. If you don't have these terminals,
- X you probably don't need this (but no point in taking it
- X out unless you're low on space).
- X
- The macros have been rewritten from scratch. The most noteable change is
- that they are no longer stored in binary files. The write-macros-to-file
- command writes a file which is suitable for use with the source command.
- So you can have actual macro definitions in your .joverc if you want. If
- you have lots of macros defined in the old format, you can use the
- macvert program to convert them to the new style. You say
- X macvert old-style-macros-file > new-style-macro-file
- X
- X"doc/system.rc" and "doc/example.rc" are jove initialization files.
- X"system.rc" is the "system" rc file here at UoR, and it gets ready every
- time JOVE starts up FOR EVERYONE. ("make install" should copy the
- system-wide .joverc to the right place automatically.) After that JOVE
- reads an initialization file in the user's home directory. "example.rc"
- is my personal .joverc.
- X
- The files "jove.[12345]" in DOC are the official JOVE manual. I got
- permission from Richard Stallman to use his manual for the original EMACS,
- modifying it where necessary for JOVE. Lots of work was done by Brian
- Harvey on this manual.
- X
- There are man pages for jove and teachjove. Teachjove is for people who
- have never used EMACS style editors. It is an interactive tutorial, THE
- tutorial written by Stallman for the original EMACS, only slightly
- modified for JOVE in the appropriate places. The man pages are
- completely up to date, thanks to me.
- X
- Thanks to Jay (hack) Fenlason for writing the original pty code.
- X
- Thanks to Dave Curry at Purdue for putting in tons of time and effort
- into getting JOVE ready. It just wouldn't be working without his help.
- X
- Thanks to Jeff Mc Carrell at Berkeley for finding bugs and adding
- features, in particular, the comment formatter.
- X
- Thanks to Karl Gegenfurtner for making the PC version.
- X
- X(Thanks to Brian Harvey for teaching me about linked lists ...)
- X
- Good luck, have fun.
- X
- X Jonathan Payne (jpayne@cs.rochester.edu until '88)
- END_OF_FILE
- if test 8923 -ne `wc -c <'./README'`; then
- echo shar: \"'./README'\" unpacked with wrong size!
- fi
- # end of './README'
- fi
- if test -f './fmt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./fmt.c'\"
- else
- echo shar: Extracting \"'./fmt.c'\" \(7964 characters\)
- sed "s/^X//" >'./fmt.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X#include "jove.h"
- X#include "io.h"
- X#include "termcap.h"
- X
- X#ifdef MAC
- X# include "mac.h"
- X#else
- X# include <varargs.h>
- X#endif
- X
- X#ifdef MAC
- X# undef private
- X# define private
- X#endif
- X
- X#ifdef LINT_ARGS
- private void
- X doformat(File *, char *, ...),
- X outld(long, int),
- X pad(int, int),
- X PPchar(int, char *),
- X putld(long, int),
- X puts(char *);
- X#else
- private void
- X doformat(),
- X outld(),
- X pad(),
- X PPchar(),
- X putld(),
- X puts();
- X#endif /* LINT_ARGS */
- X
- X#ifdef MAC
- X# undef private
- X# define private static
- X#endif
- X
- X
- char mesgbuf[MESG_SIZE];
- X
- X/* VARARGS2 */
- X
- void
- format(buf, len, fmt, ap)
- char *buf,
- X *fmt;
- va_list ap;
- X{
- X File strbuf,
- X *sp = &strbuf;
- X
- X sp->f_ptr = sp->f_base = buf;
- X sp->f_fd = -1; /* Not legit for files */
- X sp->f_cnt = len;
- X sp->f_flags = F_STRING;
- X sp->f_bufsize = len;
- X
- X doformat(sp, fmt, ap);
- X putc('\0', sp);
- X}
- X
- X#ifdef IBMPC
- int specialmap = 0,
- X specialkey = 0;
- X
- X#define Empty ""
- X
- char *altseq[133] = {
- Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
- Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left",
- X"Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
- X"Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
- X"Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
- Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
- X"Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
- Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5",
- X"F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
- X"Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
- X"Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4",
- X"Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
- X"Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10",
- X"Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
- X"Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
- X"Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
- X"Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp"
- X};
- X#endif
- X
- X
- private void
- PPchar(c, str)
- int c;
- char *str;
- X{
- X char *cp = str;
- X
- X#ifdef IBMPC
- X if (specialmap || specialkey) {
- X if (c < 0 || c > 132)
- X c = 0;
- X strcpy(cp, altseq[c]);
- X } else
- X#endif
- X if (c == '\033')
- X strcpy(cp, "ESC");
- X#ifdef IBMPC /* this character is invisible */
- X else if (c == '\377') {
- X *cp = 0;
- X }
- X#endif /* IBMPC */
- X else if (c < ' ')
- X sprintf(cp, "C-%c", c + '@');
- X else if (c == '\177')
- X strcpy(cp, "^?");
- X else
- X sprintf(cp, "%c", c);
- X}
- X
- private struct fmt_state {
- X int precision,
- X width,
- X leftadj;
- X char padc;
- X File *iop;
- X} current_fmt;
- X
- private void
- putld(d, base)
- long d;
- X{
- X int length = 1;
- X long tmpd = d;
- X
- X if (current_fmt.width == 0 && current_fmt.precision) {
- X current_fmt.width = current_fmt.precision;
- X current_fmt.padc = '0';
- X }
- X while (tmpd = (tmpd / base))
- X length += 1;
- X if (d < 0)
- X length += 1;
- X if (!current_fmt.leftadj)
- X pad(current_fmt.padc, current_fmt.width - length);
- X if (d < 0) {
- X putc('-', current_fmt.iop);
- X d = -d;
- X }
- X outld(d, base);
- X if (current_fmt.leftadj)
- X pad(current_fmt.padc, current_fmt.width - length);
- X}
- X
- private void
- outld(d, base)
- long d;
- X{
- X register long n;
- X static char chars[] = {'0', '1', '2', '3', '4', '5', '6',
- X '7', '8', '9', 'a', 'b', 'c', 'd',
- X 'e', 'f'};
- X
- X if (n = (d / base))
- X outld(n, base);
- X putc((int) (chars[(int) (d % base)]), current_fmt.iop);
- X}
- X
- private void
- puts(str)
- char *str;
- X{
- X int length;
- X register char *cp;
- X
- X if (str == 0)
- X#if pyr
- X str = "";
- X#else
- X str = "(null)";
- X#endif
- X length = strlen(str);
- X if (current_fmt.precision == 0 || length < current_fmt.precision)
- X current_fmt.precision = length;
- X else
- X length = current_fmt.precision;
- X cp = str;
- X if (!current_fmt.leftadj)
- X pad(' ', current_fmt.width - length);
- X while (--current_fmt.precision >= 0)
- X putc(*cp++, current_fmt.iop);
- X if (current_fmt.leftadj)
- X pad(' ', current_fmt.width - length);
- X}
- X
- private void
- pad(c, amount)
- register int c,
- X amount;
- X{
- X while (--amount >= 0)
- X putc(c, current_fmt.iop);
- X}
- X
- private void
- doformat(sp, fmt, ap)
- register File *sp;
- register char *fmt;
- va_list ap;
- X{
- X register char c;
- X struct fmt_state prev_fmt;
- X
- X prev_fmt = current_fmt;
- X current_fmt.iop = sp;
- X
- X while (c = *fmt++) {
- X if (c != '%') {
- X putc(c, current_fmt.iop);
- X continue;
- X }
- X
- X current_fmt.padc = ' ';
- X current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
- X c = *fmt++;
- X if (c == '-') {
- X current_fmt.leftadj = YES;
- X c = *fmt++;
- X }
- X if (c == '0') {
- X current_fmt.padc = '0';
- X c = *fmt++;
- X }
- X while (c >= '0' && c <= '9') {
- X current_fmt.width = current_fmt.width * 10 + (c - '0');
- X c = *fmt++;
- X }
- X if (c == '*') {
- X current_fmt.width = va_arg(ap, int);
- X c = *fmt++;
- X }
- X if (c == '.') {
- X c = *fmt++;
- X while (c >= '0' && c <= '9') {
- X current_fmt.precision = current_fmt.precision * 10 + (c - '0');
- X c = *fmt++;
- X }
- X if (c == '*') {
- X current_fmt.precision = va_arg(ap, int);
- X c = *fmt++;
- X }
- X }
- X reswitch:
- X /* At this point, fmt points at one past the format letter. */
- X switch (c) {
- X case '%':
- X putc('%', current_fmt.iop);
- X break;
- X
- X case 'O':
- X case 'D':
- X case 'X':
- X putld(va_arg(ap, long), (c == 'O') ? 8 :
- X (c == 'D') ? 10 : 16);
- X break;
- X
- X case 'b':
- X {
- X Buffer *b = va_arg(ap, Buffer *);
- X
- X puts(b->b_name);
- X break;
- X }
- X
- X case 'c':
- X putc(va_arg(ap, int), current_fmt.iop);
- X break;
- X
- X case 'o':
- X case 'd':
- X case 'x':
- X putld((long) va_arg(ap, int), (c == 'o') ? 8 :
- X (c == 'd') ? 10 : 16);
- X break;
- X
- X case 'f': /* current command name gets inserted here! */
- X puts(LastCmd->Name);
- X break;
- X
- X case 'l':
- X c = CharUpcase(*++fmt);
- X goto reswitch;
- X
- X case 'n':
- X if (va_arg(ap, int) != 1)
- X puts("s");
- X break;
- X
- X case 'p':
- X {
- X char cbuf[20];
- X
- X PPchar(va_arg(ap, int), cbuf);
- X puts(cbuf);
- X break;
- X }
- X
- X case 's':
- X puts(va_arg(ap, char *));
- X break;
- X
- X default:
- X complain("Unknown format directive: \"%%%c\"", c);
- X }
- X }
- X current_fmt = prev_fmt;
- X}
- X
- X/* VARARGS1 */
- X
- char *
- sprint(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X va_list ap;
- X static char line[100];
- X
- X va_start(ap);
- X format(line, sizeof line, fmt, ap);
- X va_end(ap);
- X return line;
- X}
- X
- X/* VARARGS1 */
- X
- void
- printf(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X va_list ap;
- X
- X va_start(ap);
- X#ifndef IBMPC
- X doformat(stdout, fmt, ap);
- X#else /* IBMPC */
- X write_em(sprint(fmt, ap));
- X /* doformat(stdout, fmt, ap); */
- X#endif /* IBMPC */
- X va_end(ap);
- X}
- X
- X/* VARARGS1 */
- X
- void
- fprintf(fp, fmt, va_alist)
- File *fp;
- char *fmt;
- va_dcl
- X{
- X va_list ap;
- X
- X va_start(ap);
- X doformat(fp, fmt, ap);
- X va_end(ap);
- X}
- X
- X/* VARARGS2 */
- X
- void
- sprintf(str, fmt, va_alist)
- char *str,
- X *fmt;
- va_dcl
- X{
- X va_list ap;
- X
- X va_start(ap);
- X format(str, 130, fmt, ap);
- X va_end(ap);
- X}
- X
- X/* VARARGS1 */
- X
- void
- s_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X va_list ap;
- X
- X if (InJoverc)
- X return;
- X va_start(ap);
- X format(mesgbuf, sizeof mesgbuf, fmt, ap);
- X va_end(ap);
- X message(mesgbuf);
- X}
- X
- X/* VARARGS1 */
- X
- void
- f_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X va_list ap;
- X
- X va_start(ap);
- X format(mesgbuf, sizeof mesgbuf, fmt, ap);
- X va_end(ap);
- X DrawMesg(NO);
- X UpdMesg = YES; /* still needs updating (for convenience) */
- X}
- X
- X/* VARARGS1 */
- X
- void
- add_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- X{
- X int mesg_len = strlen(mesgbuf);
- X va_list ap;
- X
- X if (InJoverc)
- X return;
- X va_start(ap);
- X format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
- X va_end(ap);
- X message(mesgbuf);
- X}
- END_OF_FILE
- if test 7964 -ne `wc -c <'./fmt.c'`; then
- echo shar: \"'./fmt.c'\" unpacked with wrong size!
- fi
- # end of './fmt.c'
- fi
- if test -f './iproc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./iproc.c'\"
- else
- echo shar: Extracting \"'./iproc.c'\" \(9262 characters\)
- sed "s/^X//" >'./iproc.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X#include "jove.h"
- X#include "re.h"
- X#include <varargs.h>
- X
- X#ifdef IPROCS
- X
- int proc_child();
- X
- X#ifdef PIPEPROCS
- X# include "iproc-pipes.c"
- X#else
- X# include "iproc-ptys.c"
- X#endif
- X
- char proc_prompt[128] = "% ";
- X
- KillProcs()
- X{
- X register Process *p;
- X register int killem = -1; /* -1 means undetermined */
- X register char *yorn;
- X
- X for (p = procs; p != 0; p = p->p_next)
- X if (!isdead(p)) {
- X if (killem == -1) {
- X yorn = ask("y", "Should I kill your i-processes? ");
- X killem = (CharUpcase(*yorn) == 'Y');
- X }
- X if (killem)
- X proc_kill(p, SIGKILL);
- X }
- X}
- X
- pbuftiedp(b)
- register Buffer *b;
- X{
- X register Process *p = b->b_process;
- X
- X if (!isdead(p))
- X complain("Process %s, attached to %b, is %s.",
- X proc_cmd(p), b, pstate(p));
- X}
- X
- X/* Process receive: receives the characters in buf, and appends them to
- X the buffer associated with p. */
- X
- private
- proc_rec(p, buf)
- register Process *p;
- char *buf;
- X{
- X Buffer *saveb = curbuf;
- X register Window *w;
- X register Mark *savepoint;
- X int sameplace = NO,
- X do_disp = NO;
- X
- X if (curwind->w_bufp == p->p_buffer)
- X w = curwind;
- X else
- X w = windbp(p->p_buffer); /* Is this window visible? */
- X if (w != 0)
- X do_disp = (in_window(w, p->p_mark->m_line) != -1);
- X SetBuf(p->p_buffer);
- X savepoint = MakeMark(curline, curchar, M_FLOATER);
- X ToMark(p->p_mark); /* where output last stopped */
- X if (savepoint->m_line == curline && savepoint->m_char == curchar)
- X sameplace = YES;
- X
- X ins_str(buf, YES);
- X MarkSet(p->p_mark, curline, curchar);
- X if (!sameplace)
- X ToMark(savepoint); /* back to where we were */
- X DelMark(savepoint);
- X /* redisplay now, instead of right after the ins_str, so that
- X we don't get a bouncing effect if point is not the same as
- X the process output position */
- X if (do_disp) {
- X w->w_line = curline;
- X w->w_char = curchar;
- X redisplay();
- X }
- X SetBuf(saveb);
- X}
- X
- proc_kill(p, sig)
- register Process *p;
- X{
- X if (isdead(p))
- X return;
- X if (killpg(p->p_pid, sig) == -1)
- X s_mess("Cannot kill %s!", proc_buf(p));
- X}
- X
- X/* Free process CHILD. Do all the necessary cleaning up (closing fd's,
- X etc.). */
- X
- free_proc(child)
- Process *child;
- X{
- X register Process *p,
- X *prev = 0;
- X
- X if (!isdead(child))
- X return;
- X for (p = procs; p != child; prev = p, p = p->p_next)
- X ;
- X if (prev == 0)
- X procs = child->p_next;
- X else
- X prev->p_next = child->p_next;
- X proc_close(child); /* if not already closed */
- X
- X /* It's possible that the buffer has been given another process
- X between the time CHILD dies and CHILD's death is noticed (via
- X list-processes). So we only set it the buffer's process to
- X 0 if CHILD is still the controlling process. */
- X if (child->p_buffer->b_process == child) {
- X child->p_buffer->b_process = 0;
- X if (curbuf == child->p_buffer)
- X PopPBs();
- X }
- X {
- X Buffer *old = curbuf;
- X
- X SetBuf(child->p_buffer);
- X DelMark(child->p_mark);
- X SetBuf(old);
- X }
- X free((char *) child->p_name);
- X free((char *) child);
- X}
- X
- ProcList()
- X{
- X register Process *p,
- X *next;
- X char *fmt = "%-15s %-15s %-8s %s",
- X pidstr[16];
- X
- X if (procs == 0) {
- X message("[No subprocesses]");
- X return;
- X }
- X TOstart("Process list", TRUE);
- X
- X Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
- X Typeout(fmt, "------", "------", "--- ", "-------");
- X for (p = procs; p != 0; p = next) {
- X next = p->p_next;
- X sprintf(pidstr, "%d", p->p_pid);
- X Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
- X if (isdead(p)) {
- X free_proc(p);
- X UpdModLine = YES;
- X }
- X }
- X TOstop();
- X}
- X
- ProcNewline()
- X{
- X#ifdef ABBREV
- X MaybeAbbrevExpand();
- X#endif
- X SendData(YES);
- X}
- X
- ProcSendData()
- X{
- X#ifdef ABBREV
- X MaybeAbbrevExpand();
- X#endif
- X SendData(NO);
- X}
- X
- private
- SendData(newlinep)
- X{
- X register Process *p = curbuf->b_process;
- X register char *lp,
- X *gp; /* JF fix for better prompt handling */
- X
- X if (isdead(p))
- X return;
- X /* If the process mark was involved in a big deletion, because
- X the user hit ^W or something, then let's do some magic with
- X the process mark. Problem is that if the user yanks back the
- X text he deleted, the mark stays at the beginning of the region,
- X and so the next time SendData() is called the entire region
- X will be sent. That's not good. So, to deal with that we reset
- X the mark to the last line, after skipping over the prompt, etc. */
- X if (p->p_mark->m_flags & M_BIG_DELETE) {
- X Bufpos bp;
- X
- X p->p_mark->m_flags &= ~M_BIG_DELETE;
- X
- X DOTsave(&bp);
- X ToLast();
- X Bol();
- X /* While we're looking at a prompt, and while we're
- X moving forward. This is for people who accidently
- X set their process-prompt to ">*" which will always
- X match! */
- X while ((LookingAt(proc_prompt, linebuf, curchar)) &&
- X (REeom > curchar))
- X curchar = REeom;
- X MarkSet(p->p_mark, curline, curchar);
- X SetDot(&bp);
- X }
- X
- X if (lastp(curline)) {
- X Eol();
- X if (newlinep)
- X LineInsert(1);
- X do_rtp(p->p_mark);
- X MarkSet(p->p_mark, curline, curchar);
- X } else {
- X /* Either we're looking at a prompt, or we're not, in
- X which case we want to strip off the beginning of the
- X line anything that looks like what the prompt at the
- X end of the file is. In other words, if "(dbx) stop in
- X ProcessNewline" is the line we're on, and the last
- X line in the buffer is "(dbx) ", then we strip off the
- X leading "(dbx) " from this line, because we know it's
- X part of the prompt. But this only happens if "(dbx) "
- X isn't one of the process prompts ... follow what I'm
- X saying? */
- X Bol();
- X if (LookingAt(proc_prompt, linebuf, curchar)) {
- X do
- X curchar = REeom;
- X while ((LookingAt(proc_prompt, linebuf, curchar)) &&
- X (REeom > curchar));
- X strcpy(genbuf, linebuf + curchar);
- X Eof();
- X ins_str(genbuf, NO);
- X } else {
- X strcpy(genbuf, linebuf + curchar);
- X Eof();
- X gp = genbuf;
- X lp = linebuf;
- X while (*lp == *gp && *lp != '\0') {
- X lp += 1;
- X gp += 1;
- X }
- X ins_str(gp, NO);
- X }
- X }
- X}
- X
- ShellProc()
- X{
- X char *shbuf = "*shell*";
- X register Buffer *b;
- X
- X b = buf_exists(shbuf);
- X if (b == 0 || isdead(b->b_process))
- X proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
- X pop_wind(shbuf, NO, -1);
- X}
- X
- Iprocess()
- X{
- X extern char ShcomBuf[100],
- X *MakeName();
- X register char *command;
- X char scratch[64],
- X *bufname;
- X int cnt = 1;
- X Buffer *bp;
- X
- X command = ask(ShcomBuf, ProcFmt);
- X null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
- X bufname = MakeName(command);
- X strcpy(scratch, bufname);
- X while ((bp = buf_exists(scratch)) && !isdead(bp->b_process))
- X sprintf(scratch, "%s.%d", bufname, cnt++);
- X proc_strt(scratch, YES, Shell, ShFlags, command, (char *) 0);
- X}
- X
- proc_child()
- X{
- X union wait w;
- X register int pid;
- X
- X for (;;) {
- X#ifndef BSD4_2
- X pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
- X#else
- X pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
- X#endif
- X if (pid <= 0)
- X break;
- X kill_off(pid, w);
- X }
- X}
- X
- kill_off(pid, w)
- register int pid;
- union wait w;
- X{
- X register Process *child;
- X
- X if ((child = proc_pid(pid)) == 0)
- X return;
- X
- X UpdModLine = YES; /* we're changing state ... */
- X if (WIFSTOPPED(w))
- X child->p_state = STOPPED;
- X else {
- X child->p_state = DEAD;
- X if (WIFEXITED(w))
- X child->p_howdied = EXITED;
- X else if (WIFSIGNALED(w)) {
- X child->p_reason = w.w_termsig;
- X child->p_howdied = KILLED;
- X }
- X {
- X Buffer *save = curbuf;
- X char mesg[128];
- X
- X /* insert status message now */
- X sprintf(mesg, "[Process %s: %s]\n",
- X proc_cmd(child),
- X pstate(child));
- X SetBuf(child->p_buffer);
- X ins_str(mesg, NO);
- X SetBuf(save);
- X redisplay();
- X }
- X }
- X}
- X
- X/* Push/pod process bindings. I openly acknowledge that this is a
- X kludge, but I can't be bothered making it right. */
- X
- struct proc_bind {
- X int pb_key;
- X data_obj **pb_map;
- X data_obj *pb_push;
- X data_obj *pb_cmd;
- X struct proc_bind *pb_next;
- X};
- X
- struct proc_bind *PBinds = 0;
- X
- PopPBs()
- X{
- X register struct proc_bind *p;
- X
- X for (p = PBinds; p != 0; p = p->pb_next)
- X p->pb_map[p->pb_key] = p->pb_push;
- X}
- X
- PushPBs()
- X{
- X register struct proc_bind *p;
- X
- X for (p = PBinds; p != 0; p = p->pb_next) {
- X p->pb_push = p->pb_map[p->pb_key];
- X p->pb_map[p->pb_key] = p->pb_cmd;
- X }
- X}
- X/* VARARGS0 */
- X
- ProcBind()
- X{
- X register data_obj *d;
- X
- X if ((d = findcom(ProcFmt)) == 0)
- X return;
- X s_mess(": %f %s ", d->Name);
- X ProcB2(mainmap, EOF, d);
- X}
- X
- ProcB2(map, lastkey, cmd)
- data_obj **map,
- X *cmd;
- X{
- X register struct proc_bind *p;
- X register data_obj **nextmap;
- X int c;
- X
- X c = addgetc();
- X if (c == EOF) {
- X if (lastkey == EOF)
- X complain("[Empty key sequence]");
- X complain("[Unexpected end-of-line]");
- X } else {
- X if (nextmap = IsPrefix(map[c]))
- X ProcB2(nextmap, c, cmd);
- X else {
- X if (curbuf->b_process)
- X PopPBs();
- X
- X for (p = PBinds; p != 0; p = p->pb_next)
- X if (p->pb_key == c && p->pb_map == map)
- X break;
- X if (p == 0) {
- X p = (struct proc_bind *) emalloc(sizeof *p);
- X p->pb_next = PBinds;
- X PBinds = p;
- X }
- X p->pb_map = map;
- X p->pb_key = c;
- X p->pb_cmd = cmd;
- X
- X if (curbuf->b_process)
- X PushPBs();
- X }
- X }
- X}
- X
- X#endif /* IPROCS */
- X
- END_OF_FILE
- if test 9262 -ne `wc -c <'./iproc.c'`; then
- echo shar: \"'./iproc.c'\" unpacked with wrong size!
- fi
- # end of './iproc.c'
- fi
- if test -f './misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./misc.c'\"
- else
- echo shar: Extracting \"'./misc.c'\" \(7989 characters\)
- sed "s/^X//" >'./misc.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X#include "jove.h"
- X#include "ctype.h"
- X#include <signal.h>
- X#ifdef ANSICODES
- X#include "termcap.h"
- X#endif
- X
- void
- prCTIME()
- X{
- X s_mess(": %f %s", get_time((time_t *) 0, (char *) 0, 0, -1));
- X}
- X
- void
- ChrToOct()
- X{
- X int c,
- X slow;
- X
- X c = waitchar(&slow);
- X if (slow)
- X message(key_strokes);
- X ins_str(sprint("\\%03o", c), NO);
- X}
- X
- void
- StrLength()
- X{
- X static char inquotes[] = "Where are the quotes?";
- X char *first = StrIndex(-1, linebuf, curchar, '"'),
- X *last = StrIndex(1, linebuf, curchar + 1, '"'),
- X c;
- X int numchars = 0;
- X
- X if (first == 0 || last == 0)
- X complain(inquotes);
- X first += 1;
- X while (first < last) {
- X c = *first++;
- X if (c == '\\') {
- X int num;
- X
- X if (!isdigit(*first))
- X first += 1;
- X else {
- X num = 3;
- X while (num-- && isdigit(*first++) && first < last)
- X ;
- X }
- X }
- X numchars += 1;
- X }
- X s_mess("%d characters", numchars);
- X}
- X
- X/* Transpos cur_char with cur_char - 1 */
- X
- void
- TransChar()
- X{
- X char before;
- X
- X if (curchar == 0 || (eolp() && curchar == 1))
- X complain((char *) 0); /* BEEP */
- X if (eolp())
- X b_char(1);
- X before = linebuf[curchar - 1];
- X del_char(BACKWARD, 1);
- X f_char(1);
- X insert_c(before, 1);
- X}
- X
- X/* Switch current line with previous one */
- X
- void
- TransLines()
- X{
- X disk_line old_prev;
- X
- X if (firstp(curline))
- X return;
- X lsave();
- X old_prev = curline->l_prev->l_dline;
- X curline->l_prev->l_dline = curline->l_dline;
- X curline->l_dline = old_prev;
- X getDOT();
- X if (!lastp(curline))
- X line_move(FORWARD, 1, NO);
- X modify();
- X}
- X
- void
- Leave()
- X{
- X longjmp(mainjmp, QUIT);
- X}
- X
- X/* If argument is specified, kill that many lines down. Otherwise,
- X if we "appear" to be at the end of a line, i.e. everything to the
- X right of the cursor is white space, we delete the line separator
- X as if we were at the end of the line. */
- X
- void
- KillEOL()
- X{
- X Line *line2;
- X int char2;
- X int num = arg_value();
- X
- X if (is_an_arg()) {
- X if (num == 0) { /* Kill to beginning of line */
- X line2 = curline;
- X char2 = 0;
- X } else {
- X line2 = next_line(curline, num);
- X if ((LineDist(curline, line2) < num) || (line2 == curline))
- X char2 = length(line2);
- X else
- X char2 = 0;
- X }
- X } else if (blnkp(&linebuf[curchar])) {
- X line2 = next_line(curline, 1);
- X if (line2 == curline)
- X char2 = length(curline);
- X else
- X char2 = 0;
- X } else {
- X line2 = curline;
- X char2 = length(curline);
- X }
- X reg_kill(line2, char2, 0);
- X}
- X
- X/* kill to beginning of sentence */
- X
- void
- KillBos()
- X{
- X negate_arg_value();
- X KillEos();
- X}
- X
- X/* Kill to end of sentence */
- X
- void
- KillEos()
- X{
- X Line *line1;
- X int char1;
- X
- X line1 = curline;
- X char1 = curchar;
- X Eos();
- X reg_kill(line1, char1, 1);
- X}
- X
- void
- KillExpr()
- X{
- X Line *line1;
- X int char1;
- X
- X line1 = curline;
- X char1 = curchar;
- X FSexpr();
- X reg_kill(line1, char1, 1);
- X}
- X
- void
- EscPrefix()
- X{
- X HandlePref(pref1map);
- X}
- X
- void
- CtlxPrefix()
- X{
- X HandlePref(pref2map);
- X}
- X
- void
- MiscPrefix()
- X{
- X HandlePref(miscmap);
- X}
- X
- void
- HandlePref(map)
- data_obj **map;
- X{
- X register data_obj *cp;
- X register int c;
- X int slow;
- X
- X c = waitchar(&slow);
- X if (c == AbortChar) {
- X message("[Aborted]");
- X rbell();
- X return;
- X }
- X
- X if (slow)
- X message(key_strokes);
- X
- X cp = map[c];
- X if (cp == 0) {
- X s_mess("[%sunbound]", key_strokes);
- X rbell();
- X } else
- X ExecCmd(cp);
- X}
- X
- void
- Yank()
- X{
- X Line *line,
- X *lp;
- X Bufpos *dot;
- X
- X if (killbuf[killptr] == 0)
- X complain("[Nothing to yank!]");
- X lsave();
- X this_cmd = YANKCMD;
- X line = killbuf[killptr];
- X lp = lastline(line);
- X dot = DoYank(line, 0, lp, length(lp), curline, curchar, curbuf);
- X set_mark();
- X SetDot(dot);
- X}
- X
- void
- WtModBuf()
- X{
- X if (!ModBufs(NO))
- X message("[No buffers need saving]");
- X else
- X put_bufs(is_an_arg());
- X}
- X
- void
- put_bufs(askp)
- X{
- X register Buffer *oldb = curbuf,
- X *b;
- X
- X for (b = world; b != 0; b = b->b_next) {
- X if (!IsModified(b) || b->b_type != B_FILE)
- X continue;
- X SetBuf(b); /* Make this current Buffer */
- X if (curbuf->b_fname == 0) {
- X char *newname;
- X
- X newname = ask(NullStr, "Buffer \"%s\" needs a file name; type Return to skip: ", b->b_name);
- X if (*newname == 0)
- X continue;
- X setfname(b, newname);
- X }
- X if (askp && (yes_or_no_p("Write %s? ", curbuf->b_fname) == NO))
- X continue;
- X filemunge(curbuf->b_fname);
- X#ifndef MAC
- X#ifndef MSDOS
- X chk_mtime(curbuf, curbuf->b_fname, "save");
- X#endif /* MSDOS */
- X#endif /* MAC */
- X file_write(curbuf->b_fname, 0);
- X unmodify();
- X }
- X SetBuf(oldb);
- X}
- X
- void
- ToIndent()
- X{
- X register char *cp,
- X c;
- X
- X for (cp = linebuf; c = *cp; cp++)
- X if (c != ' ' && c != '\t')
- X break;
- X curchar = cp - linebuf;
- X}
- X
- X/* GoLine -- go to a line, usually wired to goto-line, ESC g or ESC G.
- X If no argument is specified it asks for a line number. */
- void
- GoLine()
- X{
- X Line *newline;
- X
- X#ifndef ANSICODES
- X if (!is_an_arg())
- X set_arg_value(ask_int("Line: ",10));
- X#else /* not ANSICODES */
- X if (!is_an_arg() || arg_value() <= 0) {
- X if (SP) {
- X putpad(SP, 1); /* Ask for cursor position */
- X return;
- X }
- X set_arg_value(ask_int("Line: ", 10));
- X }
- X#endif /* ANSICODES */
- X newline = next_line(curbuf->b_first, arg_value() - 1);
- X PushPntp(newline);
- X SetLine(newline);
- X}
- X
- X#ifdef ANSICODES
- void
- MoveToCursor(line, col)
- X{
- X register struct scrimage *sp = &PhysScreen[line];
- X
- X while (sp->s_id == 0)
- X sp = &PhysScreen[--line];
- X if (sp->s_flags & MODELINE)
- X complain((char *) 0);
- X if (curwind != sp->s_window)
- X SetWind(sp->s_window);
- X SetLine(sp->s_lp);
- X curchar = how_far(sp->s_lp, col);
- X}
- X
- void
- AnsiCodes()
- X{
- X int c;
- X int num1 = 0;
- X int num2;
- X static char *unsupported = "[Unsupported ANSI code received]";
- X
- X while (isdigit(c = getch()))
- X num1 = (num1 * 10) + (c - '0');
- X
- X switch (c) {
- X case ';':
- X num2 = 0;
- X while (isdigit(c = getch()))
- X num2 = (num2 * 10) + (c - '0');
- X switch (c) {
- X case 'R':
- X MoveToCursor(--num1, --num2);
- X break;
- X case 'H':
- X Eow();
- X Bol();
- X break;
- X default:
- X complain(unsupported);
- X }
- X break;
- X case 'A':
- X PrevLine();
- X break;
- X case 'B':
- X NextLine();
- X break;
- X case 'C':
- X ForChar();
- X break;
- X case 'D':
- X BackChar();
- X break;
- X case 'H':
- X Bow();
- X break;
- X case 'J':
- X if (num1 == 2) {
- X ClAndRedraw();
- X break;
- X }
- X case 'z': /* Sun function keys send <esc>[Nz */
- X switch(num1) {
- X case 193: /* L2 */
- X SetMark();
- X break;
- X case 194: /* L3 */
- X PopMark();
- X break;
- X case 195: /* L4 */
- X DelReg();
- X break;
- X case 208: /* R1 */
- X QRepSearch();
- X break;
- X case 209: /* R2 */
- X IncFSearch();
- X break;
- X case 210: /* R3 */
- X WtModBuf();
- X break;
- X case 211: /* R4 */
- X RepSearch();
- X break;
- X case 212: /* R5 */
- X IncRSearch();
- X break;
- X case 213: /* R6 */
- X Leave();
- X break;
- X case 214: /* R7 */
- X BackWord();
- X break;
- X case 215: /* R8 == UpArrow */
- X break;
- X case 216: /* R9 */
- X ForWord();
- X break;
- X case 217: /* R10 == LeftArrow */
- X break;
- X case 218: /* R11 */
- X NextWindow();
- X break;
- X case 219: /* R12 == RightArrow */
- X break;
- X case 220: /* R13 */
- X case 221: /* R14 == DownArrow */
- X break;
- X case 222: /* R15 */
- X case 225: /* F2 */
- X case 226: /* F3 */
- X case 227: /* F4 */
- X break;
- X case 228: /* F5 */
- X break;
- X case 229: /* F6 */
- X break;
- X case 230: /* F7 */
- X break;
- X case 231: /* F8 */
- X break;
- X case 232: /* F9 */
- X break;
- X default:
- X num1 = -1; /* Hack flags failure */
- X break;
- X }
- X if (num1 >= 0)
- X break;
- X case 'P':
- X PrevPage();
- X break;
- X
- X case 'Q':
- X NextPage();
- X break;
- X
- X case 'R':
- X UpScroll();
- X break;
- X
- X case 'S':
- X DownScroll();
- X break;
- X default:
- X complain(unsupported);
- X }
- X}
- X#endif /* ANSICODES */
- X
- void
- NotModified()
- X{
- X unmodify();
- X}
- X
- void
- SetLMargin()
- X{
- X LMargin = calc_pos(linebuf, curchar);
- X}
- X
- void
- SetRMargin()
- X{
- X RMargin = calc_pos(linebuf, curchar);
- X}
- END_OF_FILE
- if test 7989 -ne `wc -c <'./misc.c'`; then
- echo shar: \"'./misc.c'\" unpacked with wrong size!
- fi
- # end of './misc.c'
- fi
- if test -f './wind.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./wind.c'\"
- else
- echo shar: Extracting \"'./wind.c'\" \(9907 characters\)
- sed "s/^X//" >'./wind.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- X * is provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ***************************************************************************/
- X
- X/* This creates/deletes/divides/grows/shrinks windows. */
- X
- X#include "jove.h"
- X#include "termcap.h"
- X
- private char onlyone[] = "You only have one window!",
- X toosmall[] = "Resulting window would be too small.";
- X
- Window *curwind,
- X *fwind = 0;
- X
- X/* First line in a Window */
- X
- int
- FLine(w)
- register Window *w;
- X{
- X register Window *wp = fwind;
- X register int lineno = -1;
- X
- X do {
- X if (wp == w)
- X return lineno + 1;
- X lineno += wp->w_height;
- X wp = wp->w_next;
- X } while (wp != fwind);
- X complain("window?");
- X /* NOTREACHED */
- X}
- X
- X/* Delete `wp' from the screen. If it is the only window left
- X on the screen, then complain. It gives its body
- X to the next window if there is one, otherwise the previous
- X window gets the body. */
- X
- void
- del_wind(wp)
- register Window *wp;
- X{
- X register Window *prev = wp->w_prev;
- X
- X if (one_windp())
- X complain(onlyone);
- X
- X wp->w_prev->w_next = wp->w_next;
- X wp->w_next->w_prev = wp->w_prev;
- X
- X if (fwind == wp) {
- X fwind = wp->w_next;
- X fwind->w_height += wp->w_height;
- X /* Here try to do something intelligent for redisplay() */
- X SetTop(fwind, prev_line(fwind->w_top, wp->w_height));
- X if (curwind == wp)
- X SetWind(fwind);
- X } else {
- X prev->w_height += wp->w_height;
- X if (curwind == wp)
- X SetWind(prev);
- X }
- X#ifdef MAC
- X RemoveScrollBar(wp);
- X Windchange++;
- X#endif
- X free((char *) wp);
- X}
- X
- X/* Divide the window WP N times, or at least once. Complains if WP is too
- X small to be split into that many pieces. It returns the new window. */
- X
- Window *
- div_wind(wp, n)
- register Window *wp;
- X{
- X register Window *new;
- X int amt;
- X
- X if (n < 1)
- X n = 1;
- X amt = wp->w_height / (n + 1);
- X if (amt < 2)
- X complain(toosmall);
- X
- X while (--n >= 0) {
- X new = (Window *) emalloc(sizeof (Window));
- X new->w_flags = 0;
- X new->w_LRscroll = 0;
- X
- X new->w_height = amt;
- X wp->w_height -= amt;
- X
- X /* set the lines such that w_line is the center in
- X each Window */
- X new->w_line = wp->w_line;
- X new->w_char = wp->w_char;
- X new->w_bufp = wp->w_bufp;
- X new->w_top = prev_line(new->w_line, HALF(new));
- X
- X /* Link the new window into the list */
- X new->w_prev = wp;
- X new->w_next = wp->w_next;
- X new->w_next->w_prev = new;
- X wp->w_next = new;
- X#ifdef MAC
- X new->w_control = 0;
- X#endif
- X }
- X#ifdef MAC
- X Windchange++;
- X#endif
- X return new;
- X}
- X
- X/* Initialze the first window setting the bounds to the size of the
- X screen. There is no buffer with this window. See parse for the
- X setting of this window. */
- X
- void
- winit()
- X{
- X register Window *w;
- X
- X w = curwind = fwind = (Window *) emalloc(sizeof (Window));
- X w->w_line = w->w_top = 0;
- X w->w_LRscroll = 0;
- X w->w_flags = 0;
- X w->w_char = 0;
- X w->w_next = w->w_prev = fwind;
- X w->w_height = ILI;
- X#ifdef MAC
- X w->w_control = 0;
- X Windchange++;
- X#endif
- X}
- X
- X/* Change to previous window. */
- X
- void
- PrevWindow()
- X{
- X register Window *new = curwind->w_prev;
- X
- X if (Asking)
- X complain((char *) 0);
- X if (one_windp())
- X complain(onlyone);
- X SetWind(new);
- X}
- X
- X/* Make NEW the current Window */
- X
- void
- SetWind(new)
- register Window *new;
- X{
- X if (!Asking) { /* can you say kludge? */
- X curwind->w_line = curline;
- X curwind->w_char = curchar;
- X curwind->w_bufp = curbuf;
- X }
- X if (new == curwind)
- X return;
- X SetBuf(new->w_bufp);
- X if (!inlist(new->w_bufp->b_first, new->w_line)) {
- X new->w_line = curline;
- X new->w_char = curchar;
- X }
- X DotTo(new->w_line, new->w_char);
- X if (curchar > strlen(linebuf))
- X new->w_char = curchar = strlen(linebuf);
- X curwind = new;
- X}
- X
- X/* delete the current window if it isn't the only one left */
- X
- void
- DelCurWindow()
- X{
- X SetABuf(curwind->w_bufp);
- X del_wind(curwind);
- X}
- X
- X/* put the current line of `w' in the middle of the window */
- X
- void
- CentWind(w)
- register Window *w;
- X{
- X SetTop(w, prev_line(w->w_line, HALF(w)));
- X}
- X
- int ScrollStep = 0; /* full scrolling */
- X
- X/* Calculate the new topline of the window. If ScrollStep == 0
- X it means we should center the current line in the window. */
- X
- void
- CalcWind(w)
- register Window *w;
- X{
- X register int up;
- X int scr_step;
- X Line *newtop;
- X
- X if (ScrollStep == 0) /* Means just center it */
- X CentWind(w);
- X else {
- X up = inorder(w->w_line, 0, w->w_top, 0);
- X if (up == -1) {
- X CentWind(w);
- X return;
- X }
- X scr_step = (ScrollStep < 0) ? SIZE(w) + ScrollStep :
- X ScrollStep - 1;
- X if (up) /* point is above the screen */
- X newtop = prev_line(w->w_line, scr_step);
- X else
- X newtop = prev_line(w->w_line, (SIZE(w) - 1 - scr_step));
- X if (LineDist(newtop, w->w_top) >= SIZE(w) - 1)
- X CentWind(w);
- X else
- X SetTop(w, newtop);
- X }
- X}
- X
- X/* This is bound to C-X 4 [BTF]. To make the screen stay the
- X same we have to remember various things, like the current
- X top line in the current window. It's sorta gross, but it's
- X necessary because of the way this is implemented (i.e., in
- X terms of do_find(), do_select() which manipulate the windows. */
- X
- void
- WindFind()
- X{
- X register Buffer *obuf = curbuf,
- X *nbuf;
- X Line *ltop = curwind->w_top;
- X Bufpos savedot;
- X extern void
- X FindTag(),
- X BufSelect(),
- X FindFile();
- X
- X DOTsave(&savedot);
- X
- X switch (waitchar((int *) 0)) {
- X case 't':
- X case 'T':
- X ExecCmd((data_obj *) FindCmd(FindTag));
- X break;
- X
- X case 'b':
- X case 'B':
- X ExecCmd((data_obj *) FindCmd(BufSelect));
- X break;
- X
- X case 'f':
- X case 'F':
- X ExecCmd((data_obj *) FindCmd(FindFile));
- X break;
- X
- X default:
- X complain("T: find-tag, F: find-file, B: select-buffer.");
- X }
- X
- X nbuf = curbuf;
- X SetBuf(obuf);
- X SetDot(&savedot);
- X SetTop(curwind, ltop); /* there! it's as if we did nothing */
- X
- X if (one_windp())
- X (void) div_wind(curwind, 1);
- X
- X tiewind(curwind->w_next, nbuf);
- X SetWind(curwind->w_next);
- X}
- X
- X/* Go into one window mode by deleting all the other windows */
- X
- void
- OneWindow()
- X{
- X while (curwind->w_next != curwind)
- X del_wind(curwind->w_next);
- X}
- X
- Window *
- windbp(bp)
- register Buffer *bp;
- X{
- X
- X register Window *wp = fwind;
- X
- X if (bp == 0)
- X return 0;
- X do {
- X if (wp->w_bufp == bp)
- X return wp;
- X wp = wp->w_next;
- X } while (wp != fwind);
- X return 0;
- X}
- X
- X/* Change window into the next window. Curwind becomes the new window. */
- X
- void
- NextWindow()
- X{
- X register Window *new = curwind->w_next;
- X
- X if (Asking)
- X complain((char *) 0);
- X if (one_windp())
- X complain(onlyone);
- X SetWind(new);
- X}
- X
- X/* Scroll the next Window */
- X
- void
- PageNWind()
- X{
- X if (one_windp())
- X complain(onlyone);
- X NextWindow();
- X NextPage();
- X PrevWindow();
- X}
- X
- Window *
- w_nam_typ(name, type)
- register char *name;
- X{
- X register Window *w;
- X register Buffer *b;
- X
- X b = buf_exists(name);
- X w = fwind;
- X if (b) do {
- X if (w->w_bufp == b)
- X return w;
- X } while ((w = w->w_next) != fwind);
- X
- X w = fwind;
- X do {
- X if (w->w_bufp->b_type == type)
- X return w;
- X } while ((w = w->w_next) != fwind);
- X
- X return 0;
- X}
- X
- X/* Put a window with the buffer `name' in it. Erase the buffer if
- X `clobber' is non-zero. */
- X
- void
- pop_wind(name, clobber, btype)
- register char *name;
- X{
- X register Window *wp;
- X register Buffer *newb;
- X
- X if (newb = buf_exists(name))
- X btype = -1; /* if the buffer exists, don't change
- X it's type */
- X if ((wp = w_nam_typ(name, btype)) == 0) {
- X if (one_windp())
- X SetWind(div_wind(curwind, 1));
- X else
- X PrevWindow();
- X } else
- X SetWind(wp);
- X
- X newb = do_select((Window *) 0, name);
- X if (clobber) {
- X initlist(newb);
- X newb->b_modified = NO;
- X }
- X tiewind(curwind, newb);
- X if (btype != -1)
- X newb->b_type = btype;
- X SetBuf(newb);
- X}
- X
- void
- GrowWindow()
- X{
- X WindSize(curwind, abs(arg_value()));
- X}
- X
- void
- ShrWindow()
- X{
- X WindSize(curwind, -abs(arg_value()));
- X}
- X
- X/* Change the size of the window by inc. First arg is the window,
- X second is the increment. */
- X
- void
- WindSize(w, inc)
- register Window *w;
- register int inc;
- X{
- X if (one_windp())
- X complain(onlyone);
- X
- X if (inc == 0)
- X return;
- X else if (inc < 0) { /* Shrinking this Window. */
- X if (w->w_height + inc < 2)
- X complain(toosmall);
- X w->w_height += inc;
- X w->w_prev->w_height -= inc;
- X } else /* Growing the window. */
- X WindSize(w->w_next, -inc);
- X#ifdef MAC
- X Windchange++;
- X#endif
- X}
- X
- X/* Set the topline of the window, calculating its number in the buffer.
- X This is for numbering the lines only. */
- X
- void
- SetTop(w, line)
- Window *w;
- register Line *line;
- X{
- X register Line *lp = w->w_bufp->b_first;
- X register int num = 0;
- X
- X w->w_top = line;
- X if (w->w_flags & W_NUMLINES) {
- X while (lp) {
- X num += 1;
- X if (line == lp)
- X break;
- X lp = lp->l_next;
- X }
- X w->w_topnum = num;
- X }
- X}
- X
- void
- WNumLines()
- X{
- X curwind->w_flags ^= W_NUMLINES;
- X SetTop(curwind, curwind->w_top);
- X}
- X
- void
- WVisSpace()
- X{
- X curwind->w_flags ^= W_VISSPACE;
- X ClAndRedraw();
- X}
- X
- X/* Return the line number that `line' occupies in `windes' */
- X
- int
- in_window(windes, line)
- register Window *windes;
- register Line *line;
- X{
- X register int i;
- X register Line *top = windes->w_top;
- X
- X for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
- X if (top == line)
- X return FLine(windes) + i;
- X return -1;
- X}
- X
- void
- SplitWind()
- X{
- X SetWind(div_wind(curwind, is_an_arg() ? (arg_value() - 1) : 1));
- X}
- X
- X/* Goto the window with the named buffer. If no such window
- X exists, pop one and attach the buffer to it. */
- void
- GotoWind()
- X{
- X extern Buffer *lastbuf;
- X char *bname;
- X Window *w;
- X
- X bname = ask_buf(lastbuf);
- X w = curwind->w_next;
- X do {
- X if (w->w_bufp->b_name == bname) {
- X SetABuf(curbuf);
- X SetWind(w);
- X return;
- X }
- X w = w->w_next;
- X } while (w != curwind);
- X SetABuf(curbuf);
- X pop_wind(bname, NO, -1);
- X}
- X
- void
- ScrollRight()
- X{
- X int amt = (is_an_arg() ? arg_value() : 10);
- X
- X if (curwind->w_LRscroll - amt < 0)
- X curwind->w_LRscroll = 0;
- X else
- X curwind->w_LRscroll -= amt;
- X UpdModLine = YES;
- X}
- X
- void
- ScrollLeft()
- X{
- X int amt = (is_an_arg() ? arg_value() : 10);
- X
- X curwind->w_LRscroll += amt;
- X UpdModLine = YES;
- X}
- END_OF_FILE
- if test 9907 -ne `wc -c <'./wind.c'`; then
- echo shar: \"'./wind.c'\" unpacked with wrong size!
- fi
- # end of './wind.c'
- fi
- echo shar: End of archive 4 \(of 21\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-